
#ifndef __TASK_H__
#define __TASK_H__

// Task States
#define TASK_STATE_READY	(1<<0)
#define TASK_STATE_RUNING	(1<<1)
#define TASK_STATE_WAITING	(1<<2)
#define TASK_STATE_ZOMBI	(1<<3)

// Task Control Block
struct TCB
{
	struct TCB* next;
	struct TCB* prev;

	unsigned int id;				// task id
	unsigned int prio;				// task priority
	unsigned int state;				// task state

	unsigned int basePrio;

	unsigned char *stackAddr;		// task stack address
	unsigned long *stackPoint;		// task stack point
	unsigned int stackSize;		// task stack size

	int (*taskFunction)(void *);	// task main address
	void *args;

	unsigned int timeQuantum;
};

struct TCB* currentTask;	// Task's TCB(Task Control Block) pointer to the current running task

// Task Queue
struct TASK_QUEUE
{
	struct TCB* next;
	struct TCB* prev;
};

// Context Frame
struct CONTEXT_FRAME
{
	unsigned long cpsr;
	unsigned long r0;
	unsigned long r1;
	unsigned long r2;
	unsigned long r3;
	unsigned long r4;
	unsigned long r5;
	unsigned long r6;
	unsigned long r7;
	unsigned long r8;
	unsigned long r9;
	unsigned long r10;
	unsigned long r11;
	unsigned long r12;
	unsigned long r13;
	unsigned long lr;
	unsigned long pc;
};

/* ------------------------------------
 * Task Management API
 *------------------------------------*/
int InitTask(void);
int TaskCreate(struct TCB *,int(*)(void *),void *,unsigned int,unsigned char *,unsigned int);
void TaskInitContext(struct TCB*);
int TaskExit(void);
int TaskGetId(void);
int TaskYield(void);
int TaskGetPriority(void);
void TaskSetPriority(int);
void TaskPriorityInherit(struct TCB *, unsigned int);
void TaskPriorityDisinherit(struct TCB *);
int InitTaskMain(void *);

/* ------------------------------------
 * Scheduler API
 *------------------------------------*/
void InitScheduler(void);
void DoScheduling(void);
void ContextSwitch();
struct TCB* TaskSelect(void);
int TaskEnqueue(struct TCB* task);
int TaskDequeue(struct TCB* task);
int SetBitmapIndex(unsigned int);
int ClearBitmapIndex(unsigned int);
void TaskEventRegister(unsigned int);
void TaskEventNotify(unsigned int);

int TaskWait(struct TASK_QUEUE *, struct TCB* task);
int TaskWakeup(struct TASK_QUEUE *, struct TCB* task);
int TaskWakeupAll(struct TASK_QUEUE *);

void TaskEventRegister(unsigned int);
void TaskEventNotify(unsigned int);




#endif /* TASK_H_ */
